<?php

namespace App\Kuafu\Pay\Jobs;

use App\Kuafu\Pay\BasePay;
use App\Kuafu\Pay\Enum\BasePayEnum;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Pay\Model\RefundStreamModel;
use App\Kuafu\Pay\Service\PayService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class RefundPolling implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 200;
    const QUEUE_NAME = '{RMS-API-REFUND}';

    private $payNo;
    private $refundNo;

    const DELAY_SECOND = 30;

    /**
     * Create a new job instance.
     * @param string $refundNo
     * @return void
     */
    public function __construct(string $refundNo, string $payNo)
    {
        $this->refundNo = $refundNo;
        $this->payNo    = $payNo;
    }

    public function handle()
    {
        Log::info("RefundPolling........refundNo:{$this->refundNo} payNo:{$this->payNo}");

        if (!$this->refundNo || !$this->payNo) {
            Log::info("RefundPolling refundNo/payNo null");
            $this->delete();
        }

        // 查DB退款信息
        $refundStream = RefundStreamModel::query()->find($this->refundNo);
        if (!$refundStream) {
            $this->delete();
        }

        // 每次间隔5s，最大延迟≈2分钟
        if ($this->attempts() >= $this->tries) {
            Log::info("refundNo:{$this->refundNo}未查询到退款结果，自动关闭 start");

            $this->delete();
        }

        // 查三方退款信息
        $payQuery = BasePay::instance($refundStream->refundChannel, $refundStream->shopId, $refundStream->sysType)
            ->refundQuery($this->payNo, $this->refundNo);
        if (!$payQuery['status']) {

            // 查询失败，先延迟再说
            $this->release(self::DELAY_SECOND);
        }

        $payStatus = $payQuery['data']['refundStatus'] ?? BasePayEnum::REFUND_STATUS_WAIT;

        // 未退款成功，延迟
        if ($payStatus == BasePayEnum::REFUND_STATUS_WAIT) {
            $this->release(self::DELAY_SECOND);
        }

        // 退款成功
        if ($payStatus == BasePayEnum::REFUND_STATUS_OK) {

            // 更新成功状态
            RefundStreamModel::refundSuccess(
                $this->refundNo,
                $payQuery['data']['refundSuccessTime'],
                $payQuery['data']['thirdRefundNo']
            );

            if ($refundStream->callbackUrl) {

                // 己方的内部服务回调
                PayService::paySuccessCallback($refundStream->callbackUrl, PayStreamModel::OPERATE_TYPE_REFUND, $refundStream->orderId, $refundStream->refundNo);
            }
        }

        // 退款关闭
        if ($payStatus == BasePayEnum::REFUND_STATUS_ERROR) {
            Log::warning("RefundPolling refundNo:{$this->refundNo}退款失败", $payQuery);

            RefundStreamModel::refundFail($this->refundNo);

            // 己方的内部服务回调
            PayService::paySuccessCallback($refundStream->callbackUrl, PayStreamModel::OPERATE_TYPE_REFUND, $refundStream->orderId, $refundStream->refundNo);

            // 关闭
            $this->delete();
        }

        $this->delete();
    }
}
